Eliminating Intermediate Array Allocations
https://tenderlovemaking.com/2024/09/29/eliminating-intermediate-array-allocations/
CRubyでは配列の割り当てを回避する最適化が内部的に行われている
以下のコードを見たとき、毎回配列を生成するように思えるが、配列を割り当てずに最大値を返せる
code:ruby
def foo(x, y)
x, y.max
end
Ruby のスタックを配列バッファとして使用するmax関数を呼び出す
Arrayオブジェクトを作らずどうしているかというと
x, yをスタックにプッシュする
要素数が2つだと確定してるのスタックから2つの要素をポップしてmax関数を呼ぶ
code:ruby
irb(main):001* def foo(x, y)
irb(main):002* x, y.max
irb(main):003> end
=> :foo
irb(main):004> insn = RubyVM::InstructionSequence.of(method(:foo))
irb(main):005> puts insn.disasm
== disasm: #<ISeq:foo@(irb):1 (1,0)-(3,3)>
local table (size: 2, argc: 2 opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1)
2 x@0<Arg> 1 y@1<Arg>
0000 getlocal_WC_0 x@0 ( 2)LiCa
0002 getlocal_WC_0 y@1
0004 opt_newarray_send 2, :max
0007 leave
opt_newarray_send はoptimizeされた呼び出しのための特別な命令
https://www.youtube.com/watch?v=ZE6F3drGhA8